import random
from typing import List, Dict

# 定义菜品数据类型（用于类型提示）
Dish = Dict[str, str | List[str]]


def format_dish_for_display(dish_dict: Dish) -> str:
    """
    将菜品信息格式化为易读字符串
    :param dish_dict: 菜品信息字典
    :return: 格式化后的字符串
    """
    return (f"菜品名称：{dish_dict['name']}\n"
            f"主要食材：{dish_dict['main_ingredients']}\n"
            f"口味：{', '.join(dish_dict['taste'])}\n"
            f"荤素：{dish_dict['type']}\n"
            f"所属窗口：{dish_dict['canteen_window'] if dish_dict['canteen_window'] else '无'}")


def get_random_recommendations(dishes: List[Dish], count: int = 3) -> List[Dish]:
    """
    从菜品列表中随机推荐指定数量的菜品
    :param dishes: 可选菜品列表
    :param count: 推荐数量（默认3个）
    :return: 随机推荐的菜品列表
    """
    if not dishes:
        return []
    actual_count = min(count, len(dishes))
    return random.sample(dishes, actual_count)


def filter_by_spiciness(dishes: List[Dish], spiciness: str) -> List[Dish]:
    """
    按辣度偏好筛选菜品
    :param dishes: 原始菜品列表
    :param spiciness: 辣度偏好（"随便"/"辣"/"微辣"/"不辣"）
    :return: 筛选后的菜品列表
    """
    if spiciness == "随便":
        return dishes

    filtered = []
    for dish in dishes:
        has_spicy = "辣" in dish["taste"]
        has_mild_spicy = "微辣" in dish["taste"]

        if spiciness == "辣" and has_spicy:
            filtered.append(dish)
        elif spiciness == "微辣" and (has_mild_spicy or has_spicy):
            filtered.append(dish)
        elif spiciness == "不辣" and not (has_spicy or has_mild_spicy):
            filtered.append(dish)

    return filtered


def filter_by_food_type(dishes: List[Dish], food_type: str) -> List[Dish]:
    """
    按荤素类型筛选菜品
    :param dishes: 原始菜品列表
    :param food_type: 荤素类型（"随便"/"荤菜"/"素菜"/"半荤半素"/"甜品"）
    :return: 筛选后的菜品列表
    """
    if food_type == "随便":
        return dishes
    return [dish for dish in dishes if dish["type"] == food_type]


def filter_by_preferences(dishes: List[Dish], spiciness: str, food_type: str) -> List[Dish]:
    """
    综合辣度和荤素偏好筛选菜品
    :param dishes: 原始菜品列表
    :param spiciness: 辣度偏好
    :param food_type: 荤素类型偏好
    :return: 复合筛选后的菜品列表
    """
    spiciness_filtered = filter_by_spiciness(dishes, spiciness)
    return filter_by_food_type(spiciness_filtered, food_type)


def filter_by_keyword(dishes: List[Dish], filter_type: str, keyword: str) -> List[Dish]:
    """
    按关键词筛选菜品（支持口味/食材/荤素/窗口）
    :param dishes: 原始菜品列表
    :param filter_type: 筛选类型（"口味"/"食材"/"荤素"/"窗口"）
    :param keyword: 筛选关键词
    :return: 筛选后的菜品列表
    """
    if filter_type == "口味":
        return [dish for dish in dishes if keyword in dish["taste"]]
    elif filter_type == "食材":
        return [dish for dish in dishes if keyword in dish["main_ingredients"]]
    elif filter_type == "荤素":
        return [dish for dish in dishes if dish["type"] == keyword]
    elif filter_type == "窗口":
        return [dish for dish in dishes if dish["canteen_window"] == keyword]
    return []


def get_recommendations(dishes: List[Dish], spiciness: str, food_type: str, count: int = 3) -> List[Dish]:
    """
    生成菜品推荐结果
    :param dishes: 所有菜品数据
    :param spiciness: 辣度偏好
    :param food_type: 荤素类型偏好
    :param count: 推荐数量
    :return: 推荐的菜品列表（包含格式化字符串）
    """
    filtered_dishes = filter_by_preferences(dishes, spiciness, food_type)
    if not filtered_dishes:
        return ["没有找到符合条件的菜品，请调整筛选条件！"]

    recommendations = get_random_recommendations(filtered_dishes, count)
    result = [f"为您推荐以下 {len(recommendations)} 个菜品：\n"]
    for i, dish in enumerate(recommendations, 1):
        result.append(f"【推荐 {i}】\n{format_dish_for_display(dish)}\n")
    return result


def get_filtered_results(dishes: List[Dish], filter_type: str, keyword: str) -> List[str]:
    """
    获取条件筛选结果
    :param dishes: 所有菜品数据
    :param filter_type: 筛选类型
    :param keyword: 筛选关键词
    :return: 筛选结果列表（包含格式化字符串）
    """
    if not keyword:
        return ["请输入筛选关键词！"]

    filtered_dishes = filter_by_keyword(dishes, filter_type, keyword)
    if not filtered_dishes:
        return [f"没有找到 {filter_type} 为 '{keyword}' 的菜品！"]

    result = [f"找到 {len(filtered_dishes)} 个符合条件的菜品：\n"]
    for i, dish in enumerate(filtered_dishes, 1):
        result.append(f"【菜品 {i}】\n{format_dish_for_display(dish)}\n")
    return result


def view_all_dishes(dishes: List[Dish]) -> List[str]:
    """
    格式化所有菜品信息
    :param dishes: 所有菜品数据
    :return: 格式化后的菜品列表字符串
    """
    if not dishes:
        return ["暂无菜品信息！"]

    result = [f"共有 {len(dishes)} 个菜品：\n"]
    for i, dish in enumerate(dishes, 1):
        result.append(f"【菜品 {i}】\n{format_dish_for_display(dish)}\n")
    return result